#include "gpsthread.h"

GPSThread::GPSThread() : coordMutex(), currentCoord(0,0), information(),
    stopped(false), dataactual(false), name(""), settings()
{
    coordMutex.unlock();
    nmea_zero_INFO(&information);
}

GPSThread::~GPSThread()
{}

bool GPSThread::GetCoordinates(GeoCoordinates &aCoord)
{
    coordMutex.lock();
    aCoord.SetLatitude(currentCoord.GetLatitude());
    aCoord.SetLongitude(currentCoord.GetLongitude());
    coordMutex.unlock();
    return dataactual;
}

bool GPSThread::GetInfo(nmeaINFO &aInfo)
{
    coordMutex.lock();
    nmea_zero_INFO(&aInfo);
    aInfo = information;
    coordMutex.unlock();
    return dataactual;
}

void GPSThread::Setup(const SerialPortSettings &aSettings, const QString &aName)
{
    name = aName;
    settings = aSettings;
}

void GPSThread::stop(void)
{
    stopped = true;
}

void GPSThread::run(void)
{
    stopped = false;
    AbstractSerial receiver;
    receiver.setDeviceName(name);
#if defined (Q_OS_UNIX)
    receiver.setCharIntervalTimeout(5000);//5 msec
#elif defined (Q_OS_WIN)
    receiver.setTotalReadConstantTimeout(100);
#endif
    if(receiver.open(AbstractSerial::ReadOnly | AbstractSerial::Unbuffered))
    {
        receiver.setBaudRate(settings.BaudRate);
        receiver.setDataBits(settings.DataBits);
        receiver.setStopBits(settings.StopBits);
        receiver.setFlowControl(settings.FlowControl);
        receiver.setParity(settings.Parity);
        nmeaINFO info;
        nmeaPARSER parser;
        nmea_zero_INFO(&info);
        nmea_parser_init(&parser);
        while(!stopped)
        {
            if((receiver.bytesAvailable() > 80) && receiver.waitForReadyRead())
            {
                // чтение строки из COM-порта
                char tmpString[1024];
                receiver.readLine(tmpString, 1024);
                // разбор NMEA-строки
                nmea_parse(&parser, tmpString, (int)strlen(tmpString), &info);
                dataactual = info.satinfo.inuse > cMINSAT;
                // установка полученных координат
                coordMutex.lock();
                information = info;
                int tmp_lat_grad = 0;
                tmp_lat_grad=info.lat / 100;
                currentCoord.SetLatitude(tmp_lat_grad + (info.lat - tmp_lat_grad * 100) / 60.);
                int tmp_lon_grad = 0;
                tmp_lon_grad=info.lon / 100;
                currentCoord.SetLongitude(tmp_lon_grad + (info.lon - tmp_lon_grad * 100) / 60.);
                coordMutex.unlock();
                emit CoordinatesChanged();
            }
            else
                sleep(1);
        }
        nmea_parser_destroy(&parser);
        nmea_zero_INFO(&information);
        receiver.close();
    }
    dataactual = false;
}
